
package org.bridgen.lang.semantics.ast;
import java.util.*;



public class Grammar extends ASTNode<ASTNode> implements Cloneable {
    public void flushCache() {
        super.flushCache();
        importedGrammars_computed = false;
        importedGrammars_value = null;
        Grammar_nodeDecls_visited = -1;
        Grammar_nodeDecls_computed = false;
        Grammar_nodeDecls_value = null;
    Grammar_nodeDecls_contributors = new java.util.HashSet();
        Grammar_ignoreDecls_visited = -1;
        Grammar_ignoreDecls_computed = false;
        Grammar_ignoreDecls_value = null;
    Grammar_ignoreDecls_contributors = new java.util.HashSet();
    }
     @SuppressWarnings({"unchecked", "cast"})  public Grammar clone() throws CloneNotSupportedException {
        Grammar node = (Grammar)super.clone();
        node.importedGrammars_computed = false;
        node.importedGrammars_value = null;
        node.in$Circle(false);
        node.is$Final(false);
    return node;
    }
     @SuppressWarnings({"unchecked", "cast"})  public Grammar copy() {
      try {
          Grammar node = (Grammar)clone();
          if(children != null) node.children = (ASTNode[])children.clone();
          return node;
      } catch (CloneNotSupportedException e) {
      }
      System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");
      return null;
    }
     @SuppressWarnings({"unchecked", "cast"})  public Grammar fullCopy() {
        Grammar res = (Grammar)copy();
        for(int i = 0; i < getNumChildNoTransform(); i++) {
          ASTNode node = getChildNoTransform(i);
          if(node != null) node = node.fullCopy();
          res.setChild(node, i);
        }
        return res;
    }
    // Declared in Compilation.jrag at line 24

	

	// From source

	private boolean fromSource = false;

    // Declared in Compilation.jrag at line 25

	public void setFromSource(boolean fromSource) {
		this.fromSource = fromSource;
	}

    // Declared in Compilation.jrag at line 28

	public boolean isFromSource() { 
		return fromSource;
	}

    // Declared in ErrorCheck.jrag at line 17


	// Method for traversal

	public Collection errorCheck() {
		Collection errorList = new ArrayList();
		nameAnalysis(errorList);
		checkPatterns(errorList);
	//	typeAnalysis();
		return errorList;
	}

    // Declared in PrettyPrint.jrag at line 38

	
    public void pp(StringBuffer buf) {
      buf.append("\n" + indent() + 
      	(isFromSource() ? "FROM SOURCE: " : "IMPORTED: ") + 
      	"grammar " + getName() + ";\n");
      for (int i = 0; i < getNumElement(); i++) {
      	getElement(i).pp(buf);
      }
    }

    // Declared in bridgit.ast at line 3
    // Declared in bridgit.ast line 12

    public Grammar() {
        super();

        setChild(new List(), 0);

    }

    // Declared in bridgit.ast at line 11


    // Declared in bridgit.ast line 12
    public Grammar(String p0, List<Element> p1) {
        setName(p0);
        setChild(p1, 0);
    }

    // Declared in bridgit.ast at line 16


  protected int numChildren() {
    return 1;
  }

    // Declared in bridgit.ast at line 19

  public boolean mayHaveRewrite() { return false; }

    // Declared in bridgit.ast at line 2
    // Declared in bridgit.ast line 12
    protected String tokenString_Name;

    // Declared in bridgit.ast at line 3

    public void setName(String value) {
        tokenString_Name = value;
    }

    // Declared in bridgit.ast at line 6

    public String getName() {
        return tokenString_Name != null ? tokenString_Name : "";
    }

    // Declared in bridgit.ast at line 2
    // Declared in bridgit.ast line 12
    public void setElementList(List<Element> list) {
        setChild(list, 0);
    }

    // Declared in bridgit.ast at line 6


    private int getNumElement = 0;

    // Declared in bridgit.ast at line 7

    public int getNumElement() {
        return getElementList().getNumChild();
    }

    // Declared in bridgit.ast at line 11


     @SuppressWarnings({"unchecked", "cast"})  public Element getElement(int i) {
        return (Element)getElementList().getChild(i);
    }

    // Declared in bridgit.ast at line 15


    public void addElement(Element node) {
        List<Element> list = getElementList();
        list.addChild(node);
    }

    // Declared in bridgit.ast at line 20


    public void setElement(Element node, int i) {
        List<Element> list = getElementList();
        list.setChild(node, i);
    }

    // Declared in bridgit.ast at line 24

    public List<Element> getElements() {
        return getElementList();
    }

    // Declared in bridgit.ast at line 27

    public List<Element> getElementsNoTransform() {
        return getElementListNoTransform();
    }

    // Declared in bridgit.ast at line 31


     @SuppressWarnings({"unchecked", "cast"})  public List<Element> getElementList() {
        return (List<Element>)getChild(0);
    }

    // Declared in bridgit.ast at line 35


     @SuppressWarnings({"unchecked", "cast"})  public List<Element> getElementListNoTransform() {
        return (List<Element>)getChildNoTransform(0);
    }

    protected boolean importedGrammars_computed = false;
    protected Collection<String> importedGrammars_value;
    // Declared in Compilation.jrag at line 34
 @SuppressWarnings({"unchecked", "cast"})     public Collection<String> importedGrammars() {
        if(importedGrammars_computed)
            return importedGrammars_value;
        int num = boundariesCrossed;
        boolean isFinal = this.is$Final();
        importedGrammars_value = importedGrammars_compute();
        if(isFinal && num == boundariesCrossed)
            importedGrammars_computed = true;
        return importedGrammars_value;
    }

    private Collection<String> importedGrammars_compute() {
		ArrayList<String> importList = new ArrayList<String>();
		for (int i = 0; i < getNumElement(); i++) {
			Element e = getElement(i);
			if (e.isImportElement()) {
				importList.add(((Import)e).getName());
			}
		}
		return importList;
	}

    // Declared in Compilation.jrag at line 50
 @SuppressWarnings({"unchecked", "cast"})     public boolean isSGLRGrammar() {
        boolean isSGLRGrammar_value = isSGLRGrammar_compute();
        return isSGLRGrammar_value;
    }

    private boolean isSGLRGrammar_compute() {
		for (int i = 0; i < getNumElement(); i++) {
			Element e = getElement(i);
			if (e.isForSGLR()) {
				return true;
			}
		}
		return false;
	}

    // Declared in NameAnalysis.jrag at line 259
 @SuppressWarnings({"unchecked", "cast"})     public NodeDecl lookupNodeDecl(String name) {
        NodeDecl lookupNodeDecl_String_value = lookupNodeDecl_compute(name);
        return lookupNodeDecl_String_value;
    }

    private NodeDecl lookupNodeDecl_compute(String name) {
		for (int i = 0; i < getNumElement(); i++) {
			Element element = getElement(i);
			if (element.isNodeDecl()) {
				NodeDecl nodeDecl = (NodeDecl)element;
				if (nodeDecl.declares(name)) {
					return nodeDecl;
				}
			}
		}
		return null;
	}

    // Declared in NameAnalysis.jrag at line 305
 @SuppressWarnings({"unchecked", "cast"})     public BridgeDecl lookupBridgeDecl(String name) {
        BridgeDecl lookupBridgeDecl_String_value = lookupBridgeDecl_compute(name);
        return lookupBridgeDecl_String_value;
    }

    private BridgeDecl lookupBridgeDecl_compute(String name) {
		for (int i = 0; i < getNumElement(); i++) {
			Element e = getElement(i);
			if (e.isBridgeDecl()) {
				BridgeDecl decl = (BridgeDecl)e;
				if (decl.includes(name)) {
					return decl;
				}
			}
		}
		return null;
	}

    // Declared in PrettyPrint.jrag at line 16
 @SuppressWarnings({"unchecked", "cast"})     public String indent() {
        String indent_value = indent_compute();
        return indent_value;
    }

    private String indent_compute() {  return " ";  }

    // Declared in PrettyPrint.jrag at line 27
    public String Define_String_indent(ASTNode caller, ASTNode child) {
        if(caller == getElementListNoTransform()) {
      int index = caller.getIndexOfChild(child);
            return indent();
        }
        return getParent().Define_String_indent(this, caller);
    }

    // Declared in TypeCodeGen.jrag at line 15
    public Grammar Define_Grammar_enclosingGrammar(ASTNode caller, ASTNode child) {
        if(caller == getElementListNoTransform()) {
      int index = caller.getIndexOfChild(child);
            return this;
        }
        return getParent().Define_Grammar_enclosingGrammar(this, caller);
    }

    // Declared in NameAnalysis.jrag at line 244
    public NodeDecl Define_NodeDecl_lookupNode(ASTNode caller, ASTNode child, String name) {
        if(caller == getElementListNoTransform()) { 
   int index = caller.getIndexOfChild(child);
{
		NodeDecl decl = lookupNodeDecl(name);		
		// If no match can be found in this grammar try another grammar
		if (decl == null) {
			ASTNode node = this;
			while (node.getParent() != null) {
				node = node.getParent();
			}
			if (!(node instanceof Program)) {
				return decl;
			} 
			return ((Program)node).lookupNode(name);
		}
		return decl;
	}
}
        return getParent().Define_NodeDecl_lookupNode(this, caller, name);
    }

    // Declared in NameAnalysis.jrag at line 290
    public BridgeDecl Define_BridgeDecl_lookupBridge(ASTNode caller, ASTNode child, String name) {
        if(caller == getElementListNoTransform()) { 
   int index = caller.getIndexOfChild(child);
{
		BridgeDecl decl = lookupBridgeDecl(name);		
		// If no match can be found in this grammar try another grammar
		if (decl == null) {
			ASTNode node = this;
			while (node.getParent() != null) {
				node = node.getParent();
			}
			if (!(node instanceof Program)) {
				return decl;
			} 
			return ((Program)node).lookupBridge(name);
		}
		return decl;
	}
}
        return getParent().Define_BridgeDecl_lookupBridge(this, caller, name);
    }

public ASTNode rewriteTo() {
    return super.rewriteTo();
}

    protected int Grammar_nodeDecls_visited = -1;
    protected boolean Grammar_nodeDecls_computed = false;
    protected Collection Grammar_nodeDecls_value;
    // Declared in TypeCodeGen.jrag at line 19
 @SuppressWarnings({"unchecked", "cast"})     public Collection nodeDecls() {
        if(Grammar_nodeDecls_computed)
            return Grammar_nodeDecls_value;
        if(Grammar_nodeDecls_visited == boundariesCrossed)
            throw new RuntimeException("Circular definition of attr: nodeDecls in class: ");
        Grammar_nodeDecls_visited = boundariesCrossed;
        int num = boundariesCrossed;
        boolean isFinal = this.is$Final();
        Grammar_nodeDecls_value = nodeDecls_compute();
        if(isFinal && num == boundariesCrossed)
            Grammar_nodeDecls_computed = true;
        Grammar_nodeDecls_visited = -1;
        return Grammar_nodeDecls_value;
    }

    java.util.HashSet Grammar_nodeDecls_contributors = new java.util.HashSet();
    private Collection nodeDecls_compute() {
        ASTNode node = this;
        while(node.getParent() != null && !(node instanceof Program))
            node = node.getParent();
        Program root = (Program)node;
        root.collect_contributors_Grammar_nodeDecls();
        Grammar_nodeDecls_value = new ArrayList();
        for(java.util.Iterator iter = Grammar_nodeDecls_contributors.iterator(); iter.hasNext(); ) {
            ASTNode contributor = (ASTNode)iter.next();
            contributor.contributeTo_Grammar_Grammar_nodeDecls(Grammar_nodeDecls_value);
        }
        return Grammar_nodeDecls_value;
    }

    protected int Grammar_ignoreDecls_visited = -1;
    protected boolean Grammar_ignoreDecls_computed = false;
    protected Collection Grammar_ignoreDecls_value;
    // Declared in TypeCodeGen.jrag at line 25
 @SuppressWarnings({"unchecked", "cast"})     public Collection ignoreDecls() {
        if(Grammar_ignoreDecls_computed)
            return Grammar_ignoreDecls_value;
        if(Grammar_ignoreDecls_visited == boundariesCrossed)
            throw new RuntimeException("Circular definition of attr: ignoreDecls in class: ");
        Grammar_ignoreDecls_visited = boundariesCrossed;
        int num = boundariesCrossed;
        boolean isFinal = this.is$Final();
        Grammar_ignoreDecls_value = ignoreDecls_compute();
        if(isFinal && num == boundariesCrossed)
            Grammar_ignoreDecls_computed = true;
        Grammar_ignoreDecls_visited = -1;
        return Grammar_ignoreDecls_value;
    }

    java.util.HashSet Grammar_ignoreDecls_contributors = new java.util.HashSet();
    private Collection ignoreDecls_compute() {
        ASTNode node = this;
        while(node.getParent() != null && !(node instanceof Program))
            node = node.getParent();
        Program root = (Program)node;
        root.collect_contributors_Grammar_ignoreDecls();
        Grammar_ignoreDecls_value = new ArrayList();
        for(java.util.Iterator iter = Grammar_ignoreDecls_contributors.iterator(); iter.hasNext(); ) {
            ASTNode contributor = (ASTNode)iter.next();
            contributor.contributeTo_Grammar_Grammar_ignoreDecls(Grammar_ignoreDecls_value);
        }
        return Grammar_ignoreDecls_value;
    }

}
